package com.smartcampusbackend.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.Grade;
import com.smartcampusbackend.model.StudentCourse;
import com.smartcampusbackend.model.User;
import com.smartcampusbackend.model.OperationLog;
import com.smartcampusbackend.mapper.GradeMapper;
import com.smartcampusbackend.mapper.StudentCourseMapper;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.mapper.CourseMapper;
import com.smartcampusbackend.service.CourseService;
import com.smartcampusbackend.service.OperationLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;


import java.util.HashMap;
import java.time.ZoneId;
import java.time.ZonedDateTime;

@RestController
@RequestMapping("/api")
public class CourseController {
    
    private static final Logger logger = LoggerFactory.getLogger(CourseController.class);
    
    @Autowired
    private CourseService courseService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private StudentCourseMapper studentCourseMapper;
    
    @Autowired
    private GradeMapper gradeMapper;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private CourseMapper courseMapper;

    /**
     * 获取所有可选课程
     * @param studentId 学生ID
     * @return 课程列表
     */
    @GetMapping("/courses")
    public List<Course> getAllCourses(@RequestParam(required = false) String studentId) {
        logger.info("获取所有课程，studentId: {}", studentId);
        try {
            List<Course> courses;
            if (studentId != null && !studentId.isEmpty()) {
                courses = courseService.listAllCourses(studentId);
            } else {
                courses = courseService.listAllCourses();
            }
            logger.info("获取到{}门课程", courses.size());
            return courses;
        } catch (Exception e) {
            logger.error("获取所有课程失败", e);
            return List.of(); // 返回空列表而不是null
        }
    }

    /**
     * 获取学生已选课程
     * @param studentId 学生ID
     * @return 已选课程列表
     */
    @GetMapping("/users/me/courses")
    public List<Course> getSelectedCourses(@RequestParam String studentId) {
        logger.info("获取已选课程，studentId: {}", studentId);
        try {
            List<Course> courses = courseService.listSelectedCourses(studentId);
            logger.info("学生{}已选{}门课程", studentId, courses.size());
            return courses;
        } catch (Exception e) {
            logger.error("获取已选课程失败", e);
            return List.of(); // 返回空列表而不是null
        }
    }

    /**
     * 学生选课
     * @param courseId 课程ID
     * @param studentId 学生ID
     * @return 是否成功
     */
    @PostMapping("/courses/{courseId}/select")
    public Boolean selectCourse(@PathVariable String courseId, @RequestParam String studentId) {
        logger.info("选课，studentId: {}, courseId: {}", studentId, courseId);
        try {
            logger.info("转换后的ID: studentId={}, courseId={}", studentId, courseId);
            boolean result = courseService.selectCourse(studentId, courseId);
            logger.info("选课结果: {}", result ? "成功" : "失败");
            // 学生选课日志
            if (result) {
                String operatorName = "";
                User user = userMapper.selectById(studentId);
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
                if (operatorName.isEmpty()) {
                    operatorName = studentId;
                }
                OperationLog log = new OperationLog();
                log.setBusinessType("选课");
                log.setBusinessId(courseId);
                log.setOperationType("选课");
                log.setOperatorId(studentId);
                log.setOperatorName(operatorName);
                log.setOperatorRole("学生");
                log.setContent(operatorName + "选课");
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(java.util.Date.from(ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).toInstant()));
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("选课失败", e);
            return false;
        }
    }

    /**
     * 学生退课
     * @param courseId 课程ID
     * @param studentId 学生ID
     * @return 是否成功
     */
    @DeleteMapping("/courses/{courseId}/withdraw")
    public Boolean withdrawCourse(@PathVariable String courseId, @RequestParam String studentId) {
        logger.info("退课，studentId: {}, courseId: {}", studentId, courseId);
        try {
            logger.info("转换后的ID: studentId={}, courseId={}", studentId, courseId);
            boolean result = courseService.withdrawCourse(studentId, courseId);
            logger.info("退课结果: {}", result ? "成功" : "失败");
            // 学生退课日志
            if (result) {
                String operatorName = "";
                User user = userMapper.selectById(studentId);
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
                if (operatorName.isEmpty()) {
                    operatorName = studentId;
                }
                OperationLog log = new OperationLog();
                log.setBusinessType("退课");
                log.setBusinessId(courseId);
                log.setOperationType("退课");
                log.setOperatorId(studentId);
                log.setOperatorName(operatorName);
                log.setOperatorRole("学生");
                log.setContent(operatorName + "退课");
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(java.util.Date.from(ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).toInstant()));
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("退课失败", e);
            return false;
        }
    }

    /**
     * 教师获取自己的课程
     * @param teacherId 教师ID
     * @return 课程列表
     */
    @GetMapping("/teacher/courses")
    public List<Course> getTeacherCourses(@RequestParam String teacherId) {
        logger.info("获取教师课程，teacherId: {}", teacherId);
        try {
            List<Course> courses = courseService.listTeacherCourses(teacherId);
            logger.info("教师{}有{}门课程", teacherId, courses.size());
            return courses;
        } catch (Exception e) {
            logger.error("获取教师课程失败", e);
            return List.of(); // 返回空列表而不是null
        }
    }

    /**
     * 教师发布课程
     * @param course 课程信息
     * @return 是否成功
     */
    @PostMapping("/teacher/courses")
    public Boolean publishCourse(@RequestBody Course course) {
        logger.info("教师发布课程: {}", course.getName());
        try {
            boolean result = courseService.createCourse(course);
            logger.info("发布课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "";
                User user = userMapper.selectById(course.getTeacherId());
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
                if (operatorName.isEmpty()) {
                    operatorName = course.getTeacherId();
                }
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(course.getId());
                log.setOperationType("发布课程");
                log.setOperatorId(course.getTeacherId());
                log.setOperatorName(operatorName);
                log.setOperatorRole("教师");
                log.setContent(operatorName + "发布了课程：" + course.getName());
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("发布课程失败", e);
            return false;
        }
    }

    /**
     * 教师更新课程
     * @param courseId 课程ID
     * @param course 课程信息
     * @return 是否成功
     */
    @PutMapping("/teacher/courses/{courseId}")
    public Boolean updateCourse(@PathVariable String courseId, @RequestBody Course course) {
        logger.info("教师更新课程，courseId: {}", courseId);
        try {
            course.setId(courseId);
            boolean result = courseService.updateCourse(course);
            logger.info("更新课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "";
                User user = userMapper.selectById(course.getTeacherId());
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
                if (operatorName.isEmpty()) {
                    operatorName = course.getTeacherId();
                }
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(course.getId());
                log.setOperationType("编辑课程");
                log.setOperatorId(course.getTeacherId());
                log.setOperatorName(operatorName);
                log.setOperatorRole("教师");
                log.setContent(operatorName + "编辑了课程：" + course.getName());
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("更新课程失败", e);
            return false;
        }
    }

    /**
     * 教师删除课程
     * @param courseId 课程ID
     * @param teacherId 教师ID
     * @return 是否成功
     */
    @DeleteMapping("/teacher/courses/{courseId}")
    public Boolean deleteCourse(@PathVariable String courseId, @RequestParam String teacherId) {
        logger.info("教师删除课程，courseId: {}, teacherId: {}", courseId, teacherId);
        try {
            boolean result = courseService.deleteCourse(courseId, teacherId);
            logger.info("删除课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "";
                User user = userMapper.selectById(teacherId);
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
                if (operatorName.isEmpty()) {
                    operatorName = teacherId;
                }
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(courseId);
                log.setOperationType("删除课程");
                log.setOperatorId(teacherId);
                log.setOperatorName(operatorName);
                log.setOperatorRole("教师");
                log.setContent(operatorName + "删除了课程，课程ID：" + courseId);
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("删除课程失败", e);
            return false;
        }
    }

    /**
     * 管理员获取所有课程
     * @return 课程列表
     */
    @GetMapping("/admin/courses")
    public ResponseEntity<List<Map<String, Object>>> getAllCourses() {
        logger.info("管理员获取所有课程");
        List<Course> courses = courseService.listAllCourses();
        logger.info("获取到{}门课程", courses.size());
        
        // 转换为包含教师姓名的响应
        List<Map<String, Object>> response = new ArrayList<>();
        for (Course course : courses) {
            Map<String, Object> courseMap = new HashMap<>();
            courseMap.put("id", course.getId());
            courseMap.put("name", course.getName());
            courseMap.put("description", course.getDescription());
            courseMap.put("credits", course.getCredits());
            courseMap.put("capacity", course.getCapacity());
            courseMap.put("currentStudents", course.getCurrentStudents());
            courseMap.put("semester", course.getSemester());
            courseMap.put("schedule", course.getSchedule());
            courseMap.put("location", course.getLocation());
            courseMap.put("prerequisite", course.getPrerequisite());
            
            // 获取教师信息
            String teacherId = course.getTeacherId();
            courseMap.put("teacherId", teacherId);
            
            // 查询教师姓名
            try {
                User teacher = userMapper.selectById(teacherId);
                if (teacher != null) {
                    courseMap.put("teacherName", teacher.getRealName() != null ? teacher.getRealName() : teacher.getUsername());
                } else {
                    courseMap.put("teacherName", "未知教师");
                }
            } catch (Exception e) {
                logger.error("获取教师信息失败", e);
                courseMap.put("teacherName", "未知教师");
            }
            
            response.add(courseMap);
        }
        
        return ResponseEntity.ok(response);
    }

    /**
     * 管理员添加课程
     * @param course 课程信息
     * @return 是否成功
     */
    @PostMapping("/admin/courses")
    public Boolean addCourseByAdmin(@RequestBody Course course) {
        logger.info("管理员添加课程: {}", course.getName());
        try {
            boolean result = courseService.createCourse(course);
            logger.info("添加课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "管理员";
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(course.getId());
                log.setOperationType("管理员添加课程");
                log.setOperatorId("admin");
                log.setOperatorName(operatorName);
                log.setOperatorRole("管理员");
                log.setContent(operatorName + "添加了课程：" + course.getName());
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("管理员添加课程失败", e);
            return false;
        }
    }

    /**
     * 管理员更新课程
     * @param courseId 课程ID
     * @param course 课程信息
     * @return 是否成功
     */
    @PutMapping("/admin/courses/{courseId}")
    public Boolean updateCourseByAdmin(@PathVariable String courseId, @RequestBody Course course) {
        logger.info("管理员更新课程，courseId: {}", courseId);
        try {
            course.setId(courseId);
            boolean result = courseService.updateCourse(course);
            logger.info("更新课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "管理员";
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(course.getId());
                log.setOperationType("管理员编辑课程");
                log.setOperatorId("admin");
                log.setOperatorName(operatorName);
                log.setOperatorRole("管理员");
                log.setContent(operatorName + "编辑了课程：" + course.getName());
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("管理员更新课程失败", e);
            return false;
        }
    }

    /**
     * 管理员删除课程
     * @param courseId 课程ID
     * @return 是否成功
     */
    @DeleteMapping("/admin/courses/{courseId}")
    public Boolean deleteCourseByAdmin(@PathVariable String courseId) {
        logger.info("管理员删除课程，courseId: {}", courseId);
        try {
            boolean result = courseService.deleteCourseByAdmin(courseId);
            logger.info("删除课程结果: {}", result ? "成功" : "失败");
            // 日志补全
            if (result) {
                String operatorName = "管理员";
                OperationLog log = new OperationLog();
                log.setBusinessType("课程管理");
                log.setBusinessId(courseId);
                log.setOperationType("管理员删除课程");
                log.setOperatorId("admin");
                log.setOperatorName(operatorName);
                log.setOperatorRole("管理员");
                log.setContent(operatorName + "删除了课程，课程ID：" + courseId);
                log.setStatus("完成");
                log.setIsSignature(false);
                log.setCreateTime(new java.util.Date());
                operationLogService.addLog(log);
            }
            return result;
        } catch (Exception e) {
            logger.error("管理员删除课程失败", e);
            return false;
        }
    }

    /**
     * 管理员获取特定课程的学生列表
     * @param courseId 课程ID
     * @return 学生列表
     */
    @GetMapping("/admin/courses/{courseId}/students")
    public List<Map<String, Object>> getCourseStudentsByAdmin(@PathVariable String courseId) {
        logger.info("管理员获取课程学生列表，courseId: {}", courseId);
        try {
            // 获取选择了该课程的所有学生
            List<StudentCourse> studentCourses = studentCourseMapper.selectList(
                new QueryWrapper<StudentCourse>().eq("course_id", courseId)
            );
            
            List<Map<String, Object>> result = new ArrayList<>();
            for (StudentCourse sc : studentCourses) {
                Map<String, Object> studentInfo = new HashMap<>();
                
                // 获取学生信息
                User student = userMapper.selectById(sc.getStudentId());
                if (student != null) {
                    studentInfo.put("studentId", student.getId());
                    studentInfo.put("studentNumber", student.getUsername());
                    studentInfo.put("studentName", student.getRealName());
                    studentInfo.put("major", student.getMajor());
                    studentInfo.put("grade", student.getGrade());
                    
                    // 获取学生在该课程的成绩信息
                    Grade grade = gradeMapper.selectOne(
                        new QueryWrapper<Grade>()
                            .eq("student_id", student.getId())
                            .eq("course_id", courseId)
                    );
                    
                    if (grade != null) {
                        studentInfo.put("regularGrade", grade.getRegularGrade());
                        studentInfo.put("examGrade", grade.getExamGrade());
                        studentInfo.put("finalGrade", grade.getFinalGrade());
                        studentInfo.put("passed", grade.getFinalGrade() != null && grade.getFinalGrade() >= 60);
                    } else {
                        studentInfo.put("regularGrade", null);
                        studentInfo.put("examGrade", null);
                        studentInfo.put("finalGrade", null);
                        studentInfo.put("passed", false);
                    }
                    
                    result.add(studentInfo);
                }
            }
            
            logger.info("获取到{}名学生", result.size());
            return result;
        } catch (Exception e) {
            logger.error("管理员获取课程学生列表失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据院系和专业筛选课程
     */
    @GetMapping("/admin/courses/filter")
    public List<Course> filterCourses(
            @RequestParam(required = false) Long departmentId,
            @RequestParam(required = false) Long majorId) {
        logger.info("根据院系和专业筛选课程，departmentId: {}, majorId: {}", departmentId, majorId);
        return courseService.listCoursesByDepartmentAndMajor(departmentId, majorId);
    }

    /**
     * 自动选择必修课程
     */
    @PostMapping("/courses/select-required")
    public Boolean selectRequiredCourses(
            @RequestParam String studentId,
            @RequestParam Long departmentId,
            @RequestParam Long majorId) {
        logger.info("自动选择必修课程，studentId: {}, departmentId: {}, majorId: {}", studentId, departmentId, majorId);
        return courseService.selectRequiredCourses(studentId, departmentId, majorId);
    }

    /**
     * 生成课程表
     */
    @GetMapping("/users/me/course-schedule")
    public List<Map<String, Object>> getCourseSchedule(@RequestParam String studentId) {
        logger.info("生成课程表，studentId: {}", studentId);
        return courseService.generateCourseSchedule(studentId);
    }

    /**
     * 获取课程详情
     */
    @GetMapping("/courses/{courseId}")
    public ResponseEntity<?> getCourseById(@PathVariable String courseId) {
        try {
            Course course = courseMapper.selectById(courseId);
            if (course == null) {
                return ResponseEntity.status(404).body("课程不存在");
            }
            return ResponseEntity.ok(course);
        } catch (Exception e) {
            logger.error("获取课程详情失败", e);
            return ResponseEntity.status(500).body("获取课程详情失败");
        }
    }
} 